package com.zhijian.medical.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.zhijian.medical.dao.local.PcrSjpzqMapper;
import com.zhijian.medical.entity.dto.YgpcrSjpzqCovSjDto;
import com.zhijian.medical.entity.dto.YgpcrSjpzqKnbSjDto;
import com.zhijian.medical.entity.po.ExperimentProcessSampleLog;
import com.zhijian.medical.entity.po.Pcr;
import com.zhijian.medical.entity.po.PcrSjpzq;
import com.zhijian.medical.entity.vo.request.ExperimentProcessSampleSearchVo;
import com.zhijian.medical.entity.vo.request.PcrSjpzqSaveOrUpdateVo;
import com.zhijian.medical.entity.vo.request.PcrSjpzqSearchVo;
import com.zhijian.medical.entity.vo.response.ExperimentProcessSampleVo;
import com.zhijian.medical.entity.vo.response.PcrSjpzqVo;
import com.zhijian.medical.enums.*;
import com.zhijian.medical.holder.CurrentUserHolder;
import com.zhijian.medical.service.ExperimentProcessSampleLogService;
import com.zhijian.medical.service.ExperimentProcessSampleService;
import com.zhijian.medical.service.PcrService;
import com.zhijian.medical.service.PcrSjpzqService;
import com.zhijian.medical.util.AssertUtil;
import com.zhijian.medical.util.JsonUtil;
import com.zhijian.medical.util.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 荧光PCR-试剂配制区业务处理层
 *
 * @author HCG
 * @version: 1.0
 * @date 2022-08-30 15:36:15
 */
@Slf4j
@Service
public class PcrSjpzqServiceImpl implements PcrSjpzqService {

    @Autowired
    private PcrSjpzqMapper mapper;

    @Autowired
    private PcrService pcrService;

    @Autowired
    private ExperimentProcessSampleService experimentProcessSampleService;

    @Autowired
    private ExperimentProcessSampleLogService experimentProcessSampleLogService;

    @Override
    public PcrSjpzq selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public PcrSjpzq selectByPcrId(Long pcrId) {
        return mapper.selectByPcrId(pcrId);
    }

    @Override
    public PcrSjpzqVo selectVoById(Long id) {
        return mapper.selectVoById(id);
    }

    @Override
    public PcrSjpzqVo selectVoByPcrId(Long pcrId) {
        PcrSjpzqVo pcrSjpzqVo = mapper.selectVoByPcrId(pcrId);
        if (Objects.isNull(pcrSjpzqVo)) {
            return null;
        }
        Pcr pcr = pcrService.selectById(pcrId);
        if (Objects.isNull(pcr)) {
            return null;
        }
        Byte type = pcr.getType();
        PcrTypeEnum pcrTypeEnum = PcrTypeEnum.getByCode(type.intValue());
        AssertUtil.notNull(pcrTypeEnum, "类型非法");
        assert pcrTypeEnum != null;
        String sjpzqSjData = pcrSjpzqVo.getSjpzqSjData();
        switch (pcrTypeEnum) {
            case KNB:
                pcrSjpzqVo.setResult(pcr.getStatus() > PcrKnbStatusEnum.SJPZQ.getCode().byteValue() ?
                        AllExperimentationStepStatusEnum.END.getCode().byteValue() : AllExperimentationStepStatusEnum.UN_END.getCode().byteValue());
                pcrSjpzqVo.setResultStr(pcr.getStatus() > PcrKnbStatusEnum.SJPZQ.getCode().byteValue() ?
                        AllExperimentationStepStatusEnum.END.getDesc() : AllExperimentationStepStatusEnum.UN_END.getDesc());
                if (StringUtils.isNotBlank(sjpzqSjData)) {
                    pcrSjpzqVo.setSjpzqSjDataList(JsonUtil.toArray(sjpzqSjData, YgpcrSjpzqKnbSjDto.class));
                }
                break;
            case GW_HPV:
                break;
            case FA_5:
                break;
            case JAK2:
                break;
            case PIK3CA:
                break;
            case COV:
                pcrSjpzqVo.setResult(pcr.getStatus() > PcrCovStatusEnum.SJPZQ.getCode().byteValue() ?
                        AllExperimentationStepStatusEnum.END.getCode().byteValue() : AllExperimentationStepStatusEnum.UN_END.getCode().byteValue());
                pcrSjpzqVo.setResultStr(pcr.getStatus() > PcrCovStatusEnum.SJPZQ.getCode().byteValue() ?
                        AllExperimentationStepStatusEnum.END.getDesc() : AllExperimentationStepStatusEnum.UN_END.getDesc());
                if (StringUtils.isNotBlank(sjpzqSjData)) {
                    pcrSjpzqVo.setSjpzqCovSjDataList(JsonUtil.toArray(sjpzqSjData, YgpcrSjpzqCovSjDto.class));
                }
                break;
            default:
                pcrSjpzqVo.setResult(pcr.getStatus() > PcrKnbStatusEnum.SJPZQ.getCode().byteValue() ?
                        AllExperimentationStepStatusEnum.END.getCode().byteValue() : AllExperimentationStepStatusEnum.UN_END.getCode().byteValue());
                pcrSjpzqVo.setResultStr(pcr.getStatus() > PcrKnbStatusEnum.SJPZQ.getCode().byteValue() ?
                        AllExperimentationStepStatusEnum.END.getDesc() : AllExperimentationStepStatusEnum.UN_END.getDesc());
                if (StringUtils.isNotBlank(sjpzqSjData)) {
                    pcrSjpzqVo.setSjpzqSjDataList(JsonUtil.toArray(sjpzqSjData, YgpcrSjpzqKnbSjDto.class));
                }
                break;
        }
        return pcrSjpzqVo;
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public void deleteByPcrId(Long pcrId) {
        mapper.deleteByPcrId(pcrId);
    }

    @Override
    public Long insert(PcrSjpzq pcrSjpzq) {
        Date now = new Date();
        pcrSjpzq.setCreateTime(now);
        pcrSjpzq.setUpdateTime(now);
        pcrSjpzq.setSystmqj(StatusEnum.UN_NORMAL.getCode().byteValue());
        pcrSjpzq.setSjzyxqn(StatusEnum.UN_NORMAL.getCode().byteValue());
        pcrSjpzq.setKrasnrastbjc(StatusEnum.UN_NORMAL.getCode().byteValue());
        pcrSjpzq.setBraftbjc(StatusEnum.UN_NORMAL.getCode().byteValue());
        pcrSjpzq.setZslxj(StatusEnum.NORMAL.getCode().byteValue());
        pcrSjpzq.setZdq(StatusEnum.NORMAL.getCode().byteValue());
        pcrSjpzq.setCjgzt(StatusEnum.NORMAL.getCode().byteValue());
        pcrSjpzq.setSyhsop11(StatusEnum.UN_NORMAL.getCode().byteValue());
        pcrSjpzq.setSyhsop15(StatusEnum.UN_NORMAL.getCode().byteValue());
        pcrSjpzq.setSyhsop17(StatusEnum.UN_NORMAL.getCode().byteValue());
        pcrSjpzq.setSyhsop7(StatusEnum.UN_NORMAL.getCode().byteValue());
        pcrSjpzq.setSyhpro4(StatusEnum.UN_NORMAL.getCode().byteValue());
        return mapper.insert(pcrSjpzq) > 0 ? pcrSjpzq.getId() : 0L;
    }

    @Override
    public boolean update(PcrSjpzq pcrSjpzq) {
        Date now = new Date();
        pcrSjpzq.setUpdateTime(now);
        return mapper.updateByPrimaryKey(pcrSjpzq) != 0;
    }

    @Override
    public Integer count(PcrSjpzqSearchVo pcrSjpzqSearchVo) {
        return mapper.count(pcrSjpzqSearchVo);
    }

    @Override
    public List<PcrSjpzqVo> selectList(PcrSjpzqSearchVo pcrSjpzqSearchVo) {
        return mapper.selectList(pcrSjpzqSearchVo);
    }

    @Override
    public Page<PcrSjpzqVo> selectPage(PcrSjpzqSearchVo pcrSjpzqSearchVo) {
        //先直接查总数
        int count = count(pcrSjpzqSearchVo);
        //分页
        Page<PcrSjpzqVo> page = new Page<>(true, count, pcrSjpzqSearchVo.getPageNum(), pcrSjpzqSearchVo.getPageSize());
        pcrSjpzqSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<PcrSjpzqVo> responseVos = this.selectList(pcrSjpzqSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Transactional(rollbackFor = Exception.class, value = "localTransactionManager")
    @Override
    public boolean saveOrUpdate(PcrSjpzqSaveOrUpdateVo pcrSjpzqSaveOrUpdateVo) {
        Long pcrId = pcrSjpzqSaveOrUpdateVo.getPcrId();
        Pcr pcr = pcrService.selectById(pcrId);
        AssertUtil.notNull(pcr, "此实验不存在或者已被删除");
        Byte type = pcr.getType();
        PcrTypeEnum pcrTypeEnum = PcrTypeEnum.getByCode(type.intValue());
        AssertUtil.notNull(pcrTypeEnum, "类型非法");
        assert pcrTypeEnum != null;
        switch (pcrTypeEnum) {
            case KNB:
                if (pcr.getStatus() < PcrKnbStatusEnum.HSKZYQ.getCode().byteValue()) {
                    //将实验的状态修改
                    pcrService.updateByPrimaryKeySelective(Pcr.builder()
                            .id(pcrId)
                            .status(PcrKnbStatusEnum.HSKZYQ.getCode().byteValue())
                            .build());
                }
                break;
            case GW_HPV:
                break;
            case FA_5:
                break;
            case JAK2:
                break;
            case PIK3CA:
                break;
            case COV:
                if (pcr.getStatus() < PcrCovStatusEnum.HSZBQ.getCode().byteValue()) {
                    //将实验的状态修改
                    pcrService.updateByPrimaryKeySelective(Pcr.builder()
                            .id(pcrId)
                            .status(PcrKnbStatusEnum.HSZBQ.getCode().byteValue())
                            .build());
                }
                break;
            default:
                if (pcr.getStatus() < PcrKnbStatusEnum.HSKZYQ.getCode().byteValue()) {
                    //将实验的状态修改
                    pcrService.updateByPrimaryKeySelective(Pcr.builder()
                            .id(pcrId)
                            .status(PcrKnbStatusEnum.HSKZYQ.getCode().byteValue())
                            .build());
                }
                break;
        }
        List<YgpcrSjpzqKnbSjDto> sjpzqSjDataList = pcrSjpzqSaveOrUpdateVo.getSjpzqSjDataList();
        if (CollectionUtil.isNotEmpty(sjpzqSjDataList)) {
            pcrSjpzqSaveOrUpdateVo.setSjpzqSjData(JsonUtil.toString(sjpzqSjDataList));
        }
        List<YgpcrSjpzqCovSjDto> sjpzqCovSjDataList = pcrSjpzqSaveOrUpdateVo.getSjpzqCovSjDataList();
        if (CollectionUtil.isNotEmpty(sjpzqCovSjDataList)) {
            pcrSjpzqSaveOrUpdateVo.setSjpzqSjData(JsonUtil.toString(sjpzqCovSjDataList));
        }
        PcrSjpzq dbParam = new PcrSjpzq();
        BeanUtils.copyProperties(pcrSjpzqSaveOrUpdateVo, dbParam);
        PcrSjpzq oldPcrSjpzq = this.selectByPcrId(pcrSjpzqSaveOrUpdateVo.getPcrId());
        if (Objects.isNull(oldPcrSjpzq)) {
            dbParam.setJcrq(DateUtil.formatDate(new Date()));
            this.insert(dbParam);
        } else {
            dbParam.setId(oldPcrSjpzq.getId());
            this.update(dbParam);
        }
        List<ExperimentProcessSampleVo> experimentProcessSampleVos = experimentProcessSampleService.selectList(ExperimentProcessSampleSearchVo.builder()
                .mainType(ExperimentTypeEnum.PCR.getCode().byteValue())
                .experimentProcessId(pcrId)
                .build());
        //保存样本日志
        experimentProcessSampleLogService.saveBatch(experimentProcessSampleVos.stream().map(e -> ExperimentProcessSampleLog.builder()
                .sampleId(e.getId())
                .fishId(pcrId)
                .mainType(ExperimentTypeEnum.PCR.getCode().byteValue())
                .op(String.format("%s%s-%s", pcr.getName(), pcr.getProcessNumber(), PcrKnbStatusEnum.SJPZQ.getDesc()))
                .opUser(CurrentUserHolder.getUser().getName())
                .build()).collect(Collectors.toList()));
        return true;
    }

}